/* ==================================================================   
 * Created [2009-4-27 下午11:32:55] by Jon.King 
 * ==================================================================  
 * TSS 
 * ================================================================== 
 * mailTo:jinpujun@hotmail.com
 * Copyright (c) Jon.King, 2009-2012 
 * ================================================================== 
 */

package com.jinhe.tss.core.persistence;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.hibernate.HibernateException;

/**
 * @author Jon.King  2006-4-7
 * 
 * Query生成器
 * 
 * <br>示例：
 * <br>     Object[] tableInfo0 = new Object[] {"OperEnterprise", "oe", "oe.eId = o.eId and oe.id.appId = ? ", new Object[] { appGd} };
   <br>     Object[] tableInfo1 = new Object[] {"Budget", "b", "b.budgetType = 1", null };
   <br>     Object[] tablesInfo = new Object[] {tableInfo0, tableInfo1};

   <br>     HQLQueryGenerator hq = new HQLQueryGenerator(condition);
   <br>     hq.add("o", "Plan o");
   <br>     hq.setOthers(" order by o.enterpriseId, o.budgetId");
   <br>     Query query = hq.getQuery(getSession(), tablesInfo);
   
   <br>生成的HQL语句为：select o
   <br>              from Plan o, Budget b, OperEnterprise oe 
   <br>              where oe.eId = o.eId and oe.id.appId = ?  and b.budgetType = 1 
   <br>              order by o.enterpriseId, o.budgetId
 */

public class HQLQueryGenerator {
	private List<String> selects = new ArrayList<String>(); //格式为字符串 如：o.id
	private List<String> froms = new ArrayList<String>();   //格式为一个数组  {表明（实体名）,别名} {"Plan" ,"p"}
    private List<String> wheres = new ArrayList<String>();  //格式为字符串  如： "o.id <= :?"
	private List<Object> conditionValue = new ArrayList<Object>(); //格式为一个数组  {名字,值}
	private String others = "";                  //用于设置其他的，如order by等
	private QueryCondition condition = null;
	
	public HQLQueryGenerator(){		
	}
	public HQLQueryGenerator(QueryCondition qyCondition){
		this.condition = qyCondition;
	}
	
	private class SelectPart{
		private StringBuffer sb = new StringBuffer();
		public SelectPart(){
			for(Iterator<String> it = selects.iterator();it.hasNext();){
				if(sb.length() > 0){
					sb.append(", ");
				}
				sb.append((String)it.next());
			}
		}
		public String toString(){
			if(sb.length() == 0){
				return "";
			}
			return "select " + sb.toString();
		}	
	}
	
	private class FromPart{
		private StringBuffer sb = new StringBuffer();
		public FromPart(){
			for(Iterator<String> it = froms.iterator();it.hasNext();){
				if(sb.length() > 0){
					sb.append(", ");
				}
				sb.append(it.next());
			}
		}
		public String toString(){
			return " from " + sb.toString();
		}
	}
	
	private class WherePart{
		private StringBuffer sb = new StringBuffer();
		public WherePart(){
			for(Iterator<String> it = wheres.iterator();it.hasNext();){							
				if(sb.length() > 0){
					sb.append(" and ");
				}
				sb.append((String)it.next());
			}
			if(condition != null){
				if(sb.length() > 0){
					sb.append(" and ");
				}
				sb.append(condition.genHQLCondition());
			}	
		}
		public String toString(){
			if(sb.length() == 0){
				return "";
			}
			return " where " + sb.toString() + " ";
		}		
	}
	
	/**
	 * 设置参数值到Query对象中
     * 
	 * @param query
	 * @param session
	 * @param ht
	 * @param tablesInfo
	 * @return
	 * @throws HibernateException
	 */
    public  Query getQuery(EntityManager em) throws HibernateException{      
        return getQuery(em, null);
    }
    
	public  Query getQuery(EntityManager em, Object[] tablesInfo) throws HibernateException{
		String hql = genHql(tablesInfo);
        
		Query query = em.createQuery(hql);
				
		for(int i = 0; i < conditionValue.size(); i++){
			query.setParameter(i, conditionValue.get(i));
		}
		if(condition != null){
			condition.genQueryCondition(query);
		}	
		return query;
	}
	
	/**
	 * 添加查询表table，查询条件conditionStr，和参数值 Object[] params
	 * @param table
	 * @param conditionStr
	 * @param params
	 */
	private void add(String table, String conditionStr, Object[] params){
		if(table != null){
			froms.add(table);
		}
		if(conditionStr != null){
			wheres.add(conditionStr);
		}	
		if(params != null){
			for(int i = 0; i < params.length; i++){
				if(params[i] != null){
					conditionValue.add(params[i]);	
				}	
			}
		}		
	}

	/**
	 * 添加查询表table，和查询列selectStr
	 * @param selectStr
	 * @param table
	 */
	public void add(String selectStr, String table){ 
		if(selectStr != null){
			selects.add(selectStr);
		}		
		if(table != null){
			froms.add(table);
		}
	}
    
    public void add(String selectStr){ 
        add(selectStr, null);
    }
    
    public void remove(String selectStr, String table){ 
        selects.remove(selectStr);
        froms.remove(table);
    }
	/**
	 * 添加其他的条件，例如order by
	 * @param others
	 */
	public void setOthers(String others){ 
		if(others != null){
			this.others = others;
		}		
	}
	
	/**
	 * 生成hql语句
	 * @return
	 */

	private String genHql(Object[] tablesInfo){
        if(tablesInfo != null){
            for(int i = 0; i < tablesInfo.length; i++){
                Object[] tableInfo = (Object[])tablesInfo[i];                
                add((String)tableInfo[0] + " " + (String)tableInfo[1], (String)tableInfo[2], (Object[])tableInfo[3]);          
            }	
        }
	   return new SelectPart().toString() + new FromPart() + new WherePart() + this.others;	
	}
}
